//
//  IndexData.h
//  Chart
//
//  Created by CaoJun on 13-6-9.
//
//

#ifndef __Chart__IndexData__
#define __Chart__IndexData__

#include "Quotation.h"
#include "IndexConfig.h"

#include <utility>
#include <vector>
#include <string>

namespace ytx {

    namespace IndexDrawType{
        enum IndexDrawType{
            Default, Index, KIndex
        };
    }

    class EmaFormula : public std::binary_function<double, double, double> {
        const double multiplier;
    public:
        EmaFormula(int period) : multiplier(2.0f / (period + 1)) {};
        double operator() (double price, double ema) {
            return (price - ema) * multiplier + ema;
        };
    };

    class IndexData: public Quotation
    {
    protected:
        Quotation * parentData;
        bool changeFlag;
    public:
        IndexType::IndexType indexType;
        IndexType::IndexType dataType;
        IndexDrawType::IndexDrawType drawType;
        IndexChartType::IndexChartType indexChartType;
        IndexConfig para;

        std::string indexName;
        std::string lineReminded;

        IndexData(IndexConfig indexConfig);

        IndexData(IndexConfig indexConfig, int toFix);

        virtual void calculate(Quotation * data);
        virtual void updateLastest(Quotation * data);

        virtual int getDataLength() const;
        virtual bool hasData() const;
        virtual bool hasData(int index) const;

        virtual std::string getCrosshairXData(int index){return "";};
        virtual std::string getCrosshairYData(int index){return "";};
        virtual const std::vector<std::string> & getBottomSideText(SizeType::SizeType)const;
        virtual std::vector<std::pair<double, std::string> > getLeftSideText(int startIndex, int endIndex, const Rectangle & rect, const Style & style) const;
        virtual bool isChange(const Quotation * data, const IndexConfig & indexConfig);
        virtual bool isChange();
        virtual bool isSameParentData(const Quotation * data);
        virtual void clearIfParentDataChanged(const Quotation * data);
        virtual void initInfo(Quotation * data);
        std::pair<double, double> getIndexDataMinMax(int startIndex, int endIndex) const;
        virtual std::pair<double, double> getDataMinMax(int startIndex, int endIndex) const;
        virtual std::pair<double, double> getAdjustedDataMinMax(int startIndex, int endIndex, const Rectangle & rect) const;
        virtual std::pair<std::string, std::string> getTopSideInfoText() const;

        double computeSMA(double x, double y, double n ,double m);

        std::vector<double> validation(int n, std::vector<double> data);

        std::vector<double> validation(int n, int len);

        std::vector<std::vector<double> > computeMA(Quotation * quotation, int n, double KLineItem::* p, int startIndex = 0);
        std::vector<std::vector<double> > computeMA(Quotation * quotation, std::vector<int> nList, double KLineItem::* p, int startIndex = 0);
        std::vector<std::vector<double> > & computeMA(Quotation * quotation, double price, std::vector<std::vector<double> > & data, std::vector<int> nList, std::vector<double> & sum, int beginIndex, double KLineItem::* p, int divid);
        
        std::vector<std::vector<double> > computeMA(std::vector<double> q, int n, int startIndex=0);
        std::vector<std::vector<double> > computeMA(std::vector<double> q, std::vector<int> nList, int startIndex=0);
        std::vector<std::vector<double> > & computeMA(std::vector<double> q, double price, std::vector<std::vector<double> > & data, std::vector<int> nList, std::vector<double> & sum, int beginIndex, int divid = 0);

        void computeEMA(std::vector<double>::const_iterator first, std::vector<double>::const_iterator last, int period, std::vector<double>::iterator result, double padding = std::numeric_limits<double>::quiet_NaN());

        double computeStandardDeviation(const std::vector<double> & data, int n, int startIndex);

        double computeSum(const std::vector<double> & data, int begin, int len, double isDivid);

        std::vector<double> transQuote(Quotation * quotation, double KLineItem::* p, int startIndex=0, int endIndex=-1);

        Quotation * getParentData() const;

        virtual void cleanData();
    };


}

#endif /* defined(__Chart__IndexData__) */
